#include <Eigen/Dense>
#include "eigen/eigen_operation_test.h"
#include "log.h"

namespace  ldl_eigen
{
void EigenOperationTest::parallel_test()
{
    // 设置使用的线程数（0表示自动检测）
    Eigen::setNbThreads(4);  // 使用4个线程
    
    const int size = 2000;
    Eigen::MatrixXd A = Eigen::MatrixXd::Random(size, size);
    Eigen::MatrixXd B = Eigen::MatrixXd::Random(size, size);
    Eigen::MatrixXd C;
    
    // 矩阵乘法会自动使用多线程
    C = A * B;
    
    LogInfo() << "Eigen is using " << Eigen::nbThreads() << " threads";
    LogInfo() << "C(0,0) = " << C(0,0);
}

void EigenOperationTest::raw_buffer_interface()
{
    const int array_size = 8;
    int array[array_size];
    for(int i = 0; i < array_size; i++)
    {
        array[i] = i;
    }
    LogInfo() << "Eigen::Map<Eigen::Matrix<int, 2, 2>>(array): \n" << Eigen::Map<Eigen::Matrix<int, 2, 2>>(array);
    LogInfo() << "Eigen::Map<Eigen::Matrix<int, 2, 2, Eigen::RowMajor>>(array): \n" << Eigen::Map<Eigen::Matrix<int, 2, 2, Eigen::RowMajor>>(array);
    LogInfo() << "Eigen::Map<Eigen::Matrix<int, 2, 2, Eigen::RowMajor>, Eigen::Unaligned,Eigen::Stride<1,4>>(array): \n" 
        << Eigen::Map<Eigen::Matrix<int, 2, 2, Eigen::RowMajor>, Eigen::Unaligned,Eigen::Stride<1,4>>(array);
}

void EigenOperationTest::advanced_initialization()
{
    // 逗号初始化
    {
        Eigen::MatrixXd mat(3,3);
        mat << 1,2,3,4,5,6,7,8,9;
        LogInfo() << "mat: " << mat;
    }

    // 用两个向量初始化新的向量
    {
        Eigen::VectorXd a{{1,2,3}};
        Eigen::VectorXd b{{4,5,6}};
        Eigen::VectorXd c(a.size() + b.size());// 注意，需要设定大小，以触发内存申请
        c << a , b;
        LogInfo() << "a: " << a;
        LogInfo() << "b: " << b;
        LogInfo() << "c: " << c;
    }

    // 用两个矩阵，初始化新的矩阵
    {
        Eigen::MatrixXd a{{1,2},{3,4}};
        Eigen::MatrixXd b{{5,6},{7,8}};
        Eigen::MatrixXd c(4,4);
        c << a , b, b, a;
        LogInfo() << "a: " << a;
        LogInfo() << "b: " << b;
        LogInfo() << "c: " << c;
    }

    // 初始化行和列
    {
        Eigen::Matrix3d a = Eigen::Matrix3d::Zero();
        a.row(0) << 1,2,3;
        LogInfo() << "a: \n" << a;
        a.block(1,0,2,2) << 4,5,6,7;
        LogInfo() << "a: \n" << a;
        a.col(2).tail(3) << 6,9,12;
        LogInfo() << "a: \n" << a;
    }

    // 特殊矩阵和数组
    {

    }
}

void EigenOperationTest::slice_operations()
{
    // seq和seqN
    {
        Eigen::MatrixXd A = Eigen::MatrixXd::Random(7,6);
        LogInfo() << "A: " << A;

        LogInfo() << "A(Eigen::seq(2,Eigen::last), Eigen::seqN(0,3)): \n" << A(Eigen::seq(2,Eigen::last), Eigen::seqN(1,3));
        LogInfo() << "A(Eigen::seq(1,2), Eigen::seqN(2,4)): \n" << A(Eigen::seq(1,2), Eigen::seqN(2,4));
        LogInfo() << "A(Eigen::seq(1,2), Eigen::seqN(2,4)): \n" << A(Eigen::seq(1,2), Eigen::seq(2, 4, 2));
        LogInfo() << "A(Eigen::seq(1,2), Eigen::seqN(2,4)): \n" << A(Eigen::all, Eigen::seq(2, 4, 2));
    }

    // lastN
    {
        Eigen::MatrixXd A = Eigen::MatrixXd::Random(7,6);
        LogInfo() << "A: " << A;
        LogInfo() << "A(Eigen::lastN(2), Eigen::lastN(2)): \n" << A(Eigen::lastN(2), Eigen::lastN(2));
        LogInfo() << "A(Eigen::lastN(2), Eigen::lastN(2)): \n" << A(Eigen::lastN(2), Eigen::lastN(3,2));
    }

    // 索引序列
    {
        Eigen::MatrixXd A = Eigen::MatrixXd::Random(4,6);
        std::vector<int> ind{4,2,5,5,3};
        LogInfo() << "A: " << A;
        LogInfo() << "A(Eigen::all, ind): \n" << A(Eigen::all, ind);
        LogInfo() << "A(Eigen::all, {5,4,3,0,4,4}): \n" << A(Eigen::all, {5,4,3,0,4,4});
    }

    // 自定义索引列表
    {
        struct pad
        {

            Eigen::Index size() const
            {
                return out_size;
            }
            Eigen::Index operator[](Eigen::Index i) const
            {
                return std::max<Eigen::Index>(0, i - (out_size - in_size));
            }
            Eigen::Index in_size, out_size;
        };

        Eigen::Matrix3i A;
        A.reshaped() = Eigen::VectorXi::LinSpaced(9, 1, 9);
        LogInfo() << "Initial matrix A: \n" << A;
        Eigen::MatrixXi B(5, 5);
        B = A(pad{
                  3, 5},
              pad{3, 5});
        LogInfo() << "A(pad{3,N}, pad{3,N}): \n" << B;
    }
}

void EigenOperationTest::block_operations()
{
    // 取子块
    {
        Eigen::MatrixXd mat{{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}};
        LogInfo() << "mat: " << mat;

        // 取一个2*2的矩阵，起点坐标为(1,1)
        LogInfo() << "mat.block<2,2>(1,1): \n" << mat.block<2,2>(1,1);
        LogInfo() << "mat.block(1,1,2,2): \n" << mat.block(1,1,2,2);

        for(int i = 0; i <= 4; i++)
        {
            LogInfo() << "mat.block(0,0," << i << "," << i << "): \n" << mat.block(0,0,i,i);
        }
    }

    // 给子块赋值
    {
        Eigen::MatrixXd m{{1,2},{3,4}};
        Eigen::MatrixXd a = Eigen::MatrixXd::Constant(4,4,0.6);

        LogInfo() << "m: " << m;
        LogInfo() << "a: " << a;

        a.block(1,1, 2,2) = m;
        LogInfo() << "a: " << a;
    }

    // 行和列
    {
        Eigen::MatrixXd mat{{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}};
        LogInfo() << "mat: " << mat;
        LogInfo() << "mat.row(1): \n" << mat.row(1);

        mat.row(2) += 3 * mat.row(0);
        LogInfo() << "mat: " << mat;
    }

    // 边和角的块
    {
        Eigen::MatrixXd mat{{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}};
        LogInfo() << "mat: " << mat;

        LogInfo() << "mat.topRows(2): \n" << mat.topRows(2);
        LogInfo() << "mat.leftCols(2): \n" << mat.leftCols(2);
    }

    // 向量的头、尾、段
    {
        Eigen::VectorXd vec{{1,2,3,4,5,6}};
        LogInfo() << "vec: " << vec;
        LogInfo() << "vec.head(2): " << vec.head(2);
        LogInfo() << "vec.head<2>(): " << vec.head<2>();
        LogInfo() << "vec.tail(2): " << vec.tail(2);

        // 取段，索引2开始，取4个元素
        LogInfo() << "vec.segment(1,4): \n" << vec.segment(2,4);
    }
}

/**
 * 如果需要执行线性代数的运算，优先选择Matrix。如果要对应元素之间的运算，选择Array
 * Matrix和Array之间可以相互转换
 */
void EigenOperationTest::array_operations()
{
    // 数组初始化
    {
        Eigen::ArrayXXf arr(2,2);
        arr(0,0) = 1.0;
        arr(0,1) = 2.0;
        arr(1,0) = 3.0;
        arr(1,1) = arr(0,1) + arr(1,0);
        LogInfo() << "arr: \n" << arr;

        arr << 1.0, 2.0, 3.0, 4.0;
        LogInfo() << "arr: \n" << arr;
    }

    // 加法和减法
    {
        Eigen::ArrayXXf a{{1.0, 2.0, 3.0},{4.0, 5.0, 6.0},{7.0, 8.0, 9.0}};
        Eigen::ArrayXXf b{{1.0, 2.0, 3.0},{4.0, 5.0, 6.0},{7.0, 8.0, 9.0}};

        LogInfo() << "a + b: \n" << a + b;
        LogInfo() << "a - 2: \n" << a - 2;
    }

    // Array与标量相乘
    {
        Eigen::ArrayXXf arr{{1.0, 2.0, 3.0},{4.0, 5.0, 6.0},{7.0, 8.0, 9.0}};
        double scaler{2.0};
        LogInfo() << "arr * scaler: \n" << arr * scaler;
        LogInfo() << "scaler * arr: \n" << scaler * arr;
        LogInfo() << "arr * arr: \n" << arr * arr;
    }

    // 其它按元素操作的运算
    {
        Eigen::ArrayXXf arr{{1.0, 2.0, 3.0},{4.0, 5.0, 6.0},{7.0, 8.0, 9.0}};

        LogInfo() << "arr: \n" << arr;
        LogInfo() << "arr.log(): \n" << arr.log();
        LogInfo() << "arr.abs(): \n" << arr.abs();
        LogInfo() << "arr.sqrt(): \n" << arr.sqrt();

        Eigen::ArrayXXf other{{9.0, 8.0, 7.0},{6.0, 5.0, 4.0},{3.0, 2.0, 1.0}};
        LogInfo() << "other: \n" << other;
        LogInfo() << "arr.min(other): \n" << arr.min(other);// 取形状相同的两个矩阵中的对应位置最小值组成新的矩阵
        LogInfo() << "arr.max(other): \n" << arr.max(other);// 取形状相同的两个矩阵中的对应位置最大值组成新的矩阵
    }

    /**
     * 如果需要执行线性代数的运算，优先选择Matrix。如果要对应元素之间的运算，选择Array
     * Matrix和Array之间可以相互转换
     */
    // Matrix和Array
    {
        Eigen::MatrixXd m{{1, 2}, {3, 4}};
        Eigen::MatrixXd n{{5,6},{7,8}};
        Eigen::MatrixXd result{};

        LogInfo() << "m * n: \n" << m * n;
        LogInfo() << "m.array() * n.array(): \n" << m.array() * n.array();
        LogInfo() << "m.cwiseProduct(n): \n" << m.cwiseProduct(n);
        LogInfo() << "n.array() + 4: \n" << n.array() + 4;

        LogInfo() << "(m.array() + 4).matrix() * m: \n" << (m.array() + 4).matrix() * m;
        LogInfo() << "(m.array() * n.array()).matrix() * m: \n" << (m.array() * n.array()).matrix() * m;
    }
}

void EigenOperationTest::linear_algebra_operations()
{
    // 加法和减法
    {
        Eigen::MatrixXd a{{1,2},{3,4}};
        Eigen::MatrixXd b{{1,2},{3,4}};
        auto c = a + b;
        LogInfo() << "c: \n" << c;

        // 元素数据类型不同，无法通过编译
        // {
        //     Eigen::MatrixXd a{{1,2},{3,4}};
        //     Eigen::MatrixXi b{{1,2},{3,4}};
        //     auto c = a + b;
        //     LogInfo() << "c: \n" << c;
        // }

        // 维数不同，可以编译，无法运行
        // {
        //     Eigen::MatrixXd a{{1,2},{3,4}};
        //     Eigen::MatrixXd b{{1,2,3},{4, 5, 6}};
        //     auto c = a + b;
        //     LogInfo() << "c: \n" << c;
        // }
    }

    // 矩阵与标量的运算
    {
        Eigen::MatrixXd mat{{1,2},{3,4}};
        double scalar{1.1};

        LogInfo() << "mat: \n" << mat;
        LogInfo() << "scalar: \n" << scalar;
        LogInfo() << "scalar * mat: \n" << scalar * mat;
        LogInfo() << "mat * scalar: \n" << mat * scalar;
    }

    // 转置
    {
        Eigen::MatrixXi mat{{0,1,2,3,4},{5,6,7,8,9}};
        LogInfo() << "mat: \n" << mat;
        LogInfo() << "mat.transpose(): \n" << mat.transpose();
    }

    // 共轭
    {
        Eigen::MatrixXcf mat_xcf = Eigen::MatrixXcf::Random(2, 2);
        LogInfo() << "mat_xcf: \n" << mat_xcf;
        LogInfo() << "mat_xcf.conjugate(): \n" << mat_xcf.conjugate();
    }

    // 伴随矩阵
    {
        Eigen::MatrixXd mat_xd = Eigen::MatrixXd::Random(2, 2);
        LogInfo() << "mat_xd: \n" << mat_xd;
        LogInfo() << "mat_xd.adjoint(): \n" << mat_xd.adjoint();
    }

    // 就地转置
    {
        Eigen::MatrixXd mat_xd = Eigen::MatrixXd::Random(2, 3);
        LogInfo() << "mat_xd: \n" << mat_xd;
        mat_xd.transposeInPlace();
        LogInfo() << "mat_xd.transposeInPlace(): \n" << mat_xd;
    }

    // 矩阵乘矩阵
    {
        Eigen::MatrixXd a{{1, 2},{3, 4}, {5, 6}};
        Eigen::MatrixXd b{{1, 2, 3},{4, 5, 6}};
        LogInfo() << "a: " << a;
        LogInfo() << "b: " << b;
        LogInfo() << "a * b: \n" << a * b;

        Eigen::MatrixXd mat{{1, 2},{3, 4}};
        Eigen::Vector2d u(-1, 1), v(2, 0);
        LogInfo() << "mat * mat: \n" << mat * mat;
        LogInfo() << "mat * u: \n" << mat * u;

        LogInfo() << "u.T * mat: \n" << u.transpose() * mat;
        LogInfo() << "u.T * v: \n" << u.transpose() * v;
        LogInfo() << "u * v.T: \n" << u * v.transpose();

        // Eigen::MatrixXd c;
        // c.noalias() += mat * mat;
        // LogInfo() << "c: " << c;
    }

    // 向量按元素相乘
    {
        Eigen::Vector3d v{{1,2,3}};
        Eigen::Vector3d w{{0,1,2}};

        LogInfo() << "v.dot(w): " << v.dot(w);
        LogInfo() << "v.adjoint()*w: " << v.adjoint()*w;
        LogInfo() << "v.cross(w): \n" << v.cross(w);
    }

    // 基本算术的简化运算
    {
        Eigen::MatrixXd mat{{1, 2},{3, 4}, {5, 6}};
        LogInfo() << "mat.sum(): " << mat.sum();    // 求和
        LogInfo() << "mat.prod(): " << mat.prod();  // 求乘积
        LogInfo() << "mat.mean(): " << mat.mean();  // 求平均值
        LogInfo() << "mat.minCoeff(): " << mat.minCoeff();  // 最小值
        LogInfo() << "mat.maxCoeff(): " << mat.maxCoeff();  // 最大值
        LogInfo() << "mat.trace(): " << mat.trace();    // 矩阵的迹
    }

    // 最大值最小值的索引
    {
        Eigen::MatrixXd a = Eigen::MatrixXd::Random(3,3);
        LogInfo() << "a: " << a;
        std::ptrdiff_t i, j;
        double min = a.minCoeff(&i, &j);
        LogInfo() << "min: " << min;
        LogInfo() << "i: " << i;
        LogInfo() << "j: " << j;

        Eigen::MatrixXd b = Eigen::MatrixXd::Random(4,4);
        LogInfo() << "b: " << b;
        double max = b.maxCoeff(&i, &j);
        LogInfo() << "max: " << max;
        LogInfo() << "i: " << i;
        LogInfo() << "j: " << j;
    }
}

void EigenOperationTest::test()
{
    // 动态大小矩阵
    Eigen::MatrixXd A = Eigen::MatrixXd::Random(3, 3);  // 随机初始化
    LogInfo() << "A: " << A;

    Eigen::MatrixXd B = Eigen::MatrixXd::Identity(3, 3); // 单位矩阵
    LogInfo() << "B: " << B;


    // 固定大小向量
    Eigen::Vector3d v(1.0, 2.0, 3.0);
    LogInfo() << "v: " << v;

    // 基本运算
    Eigen::MatrixXd C = A + B;                // 加法
    LogInfo() << "C: " << C;

    Eigen::MatrixXd D = A * B;                // 乘法
    LogInfo() << "D: " << D;

    double dot_product = v.dot(v);      // 逐个元素乘积求和
    LogInfo() << "dot_product: " << dot_product;

    // 解线性方程组 Ax = b
    Eigen::VectorXd b = Eigen::VectorXd::Random(3);
    LogInfo() << "b: " << b;
    Eigen::VectorXd x = A.lu().solve(b);      // LU分解求解
    LogInfo() << "x: " << x;

    LogInfo() << "A * B: " << A *B;
}

void EigenOperationTest::matrix_test()
{
    // 矩阵
    {
        Eigen::Matrix4f mat{};
        LogInfo() << "mat: \n" << mat;
    }

    // 向量（列向量）
    {
        Eigen::Vector3f vec{};
        LogInfo() << "vec: \n" << vec;
    }

    // 行向量
    {
        Eigen::RowVector3f row_vec{};
        LogInfo() << "row_vec: \n" << row_vec;
    }

    // 动态矩阵
    {
        typedef Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic> MyMatrixXd;
        MyMatrixXd my_mat;
        LogInfo() << "my_mat: " << my_mat;

        // 构造函数，全动态参数，不申请内存
        MyMatrixXd dynamic_mat;
        LogInfo() << "dynamic_mat: " << dynamic_mat;
    }

    // 部分参数是动态
    {
        // 部分参数是动态的，不申请内存
        typedef Eigen::Matrix<double, 3, Eigen::Dynamic> MyMatrix3d;
        MyMatrix3d my_mat3d;
        LogInfo() << "my_mat3d: \n" << my_mat3d;
    }

    // 指定长度的动态矩阵
    {
        // 指定长度的动态矩阵，会申请内存，但不初始化
        Eigen::MatrixXd my_mat(10, 10);
        LogInfo() << "my_mat: " << my_mat;

        // 同样指定长度的动态向量，会申请内存，但不初始化
        Eigen::VectorXd my_vec(4);
        LogInfo() << "my_vec: " << my_vec;
    }

    // 确定行、列维度的矩阵，仍然可以传入对应的行、列，正确即可
    {
        Eigen::Matrix3f a(3,3);
        LogInfo() << "a: " << a;

        // 以下代码可以编译，但无法运行
        // Eigen::Matrix3f b(2,3);
    }

    // 构造函数直接设置向量元素的值
    {
        Eigen::Vector2d vec2d(1, 2);
        LogInfo() << "vec2d: \n" << vec2d;

        Eigen::Vector3f vec3f(1, 2, 3);
        LogInfo() << "vec3f: \n" << vec3f;

        Eigen::Vector4f vec4f(1, 2, 3, 4.0);
        LogInfo() << "vec4f: \n" << vec4f;

        Eigen::Matrix<float, 5, 1> vec5f(1, 2, 3, 4.0, 5);
        LogInfo() << "vec5f: \n" << vec5f;
    }

    // 构造函数直接设置矩阵元素的值
    {
        Eigen::MatrixXi a {
            {2, 1},
            {1, 2}
        };
        LogInfo() << "a: " << a;

        Eigen::Matrix<double, 3, 2> b{
            {1,2},
            {2,1},
            {1,1}
        };
        LogInfo() << "b: \n" << b;

        Eigen::VectorXd c{{1,2,3}};
        LogInfo() << "c: " << c;

        Eigen::RowVectorXd d{{1,2,3}};
        LogInfo() << "d: " << d;
    }

    // 访问元素 通过括号传入元素索引
    {
        Eigen::MatrixXd mat(2, 2);
        mat(0, 0) = 3;
        mat(1, 0) = 2.5;
        mat(0, 1) = -1;
        mat(1, 1) = mat(1,0) + mat(0,1);
        LogInfo() << "mat: " << mat;
        LogInfo() << "mat(0): " << mat(0);
        LogInfo() << "mat(0,1): " << mat(0,1);

        Eigen::VectorXd vec(2);
        vec(0) = 4;
        vec(1) = vec(0) - 1;
        LogInfo() << "vec: " << vec;
    }

    // 逗号初始化
    {
        Eigen::MatrixXd mat(3, 3);
        mat <<  1, 2, 3,
                4, 5, 6,
                7, 8, 9;
        LogInfo() << "mat: " << mat;

        // 以下代码可以编译，但无法运行。因为没有指定行和列的大小，没有申请内存
        // Eigen::MatrixXd mat_error;
        // mat_error <<  1, 2, 3,
        //         4, 5, 6,
        //         7, 8, 9;
        // LogInfo() << "mat_error: " << mat_error;
    }

    // 矩阵维数获取及重置
    {
        Eigen::MatrixXd mat(2, 5);
        LogInfo() << "mat.row: " << mat.rows();
        LogInfo() << "mat.col: " << mat.cols();
        LogInfo() << "mat: " << mat;

        mat.resize(3, 4);
        LogInfo() << "mat.row: " << mat.rows();
        LogInfo() << "mat.col: " << mat.cols();
        LogInfo() << "mat: " << mat;
    }

    // 向量维度获取及重置
    {
        Eigen::VectorXd vec(5);
        LogInfo() << "vec.row: " << vec.rows();
        LogInfo() << "vec.col: " << vec.cols();
        LogInfo() << "vec: " << vec;

        vec.resize(3);
        LogInfo() << "vec.row: " << vec.rows();
        LogInfo() << "vec.col: " << vec.cols();
        LogInfo() << "vec: " << vec;

        // 以下代码可以编译，无法运行
        // vec.resize(3, 2);
        // LogInfo() << "vec.row: " << vec.rows();
        // LogInfo() << "vec.col: " << vec.cols();
        // LogInfo() << "vec: " << vec;
    }

    // 通过conservativeResize改变矩阵的大小，会尽量保留原值
    {
        Eigen::MatrixXd mat(2, 5);
        LogInfo() << "mat: " << mat;

        mat.conservativeResize(3, 4);
        LogInfo() << "mat: " << mat;
    }

    // resize之后的矩阵的值不会被初始化，为垃圾值
    {
        Eigen::MatrixXi mat{{0,1,2,3,4},{5,6,7,8,9}};
        LogInfo() << "mat: " << mat;

        mat.resize(3, 4);
        LogInfo() << "mat: " << mat;
    }

    // resize修改固定大小的矩阵
    {
        Eigen::Matrix4d mat;
        LogInfo() << "mat: \n" << mat;

        mat.resize(4, 4);
        LogInfo() << "mat: \n" << mat;

        // 以下代码可以编译，无法运行
        // mat.resize(4, 5);
        // LogInfo() << "mat: " << mat;
    }

    // 赋值操作
    {
        Eigen::MatrixXi a{{0,1,2,3,4},{5,6,7,8,9}};
        LogInfo() << "a: " << a;

        Eigen::MatrixXi b{{0,1,2},{3,4,5},{6,7,8}};
        LogInfo() << "b: " << b;

        b = a;
        LogInfo() << "b: " << b;
    }

    // 对固定大小的矩阵赋值
    {
        Eigen::MatrixXi a{{0,1,2,3,4},{5,6,7,8,9}};
        LogInfo() << "a: " << a;

        Eigen::Matrix3i b{{0,1,2},{3,4,5},{6,7,8}};
        LogInfo() << "b: \n" << b;

        Eigen::Matrix3i c{{8,7,6},{5,4,3},{2,1,0}};
        LogInfo() << "c: \n" << c;

        b = c;
        LogInfo() << "b: \n" << b;

        // 以下代码可以编译，但不能运行
        // b = a;
        // LogInfo() << "b: " << b;
    }

    /**
     * 如何选择固定大小矩阵还是动态大小矩阵
     * 固定大小矩阵，在栈上分配内存。动态大小矩阵在堆上分配内存。因而小矩阵可使用固定大小的矩阵。大矩阵使用动态大小矩阵。
     */

     // 其它类型
     {
        Eigen::Matrix3Xd mat_3xd{{1, 2},{3, 4},{5, 6}};
        LogInfo() << "mat_3xd: \n" << mat_3xd;

        // 以下代码可以编译，但无法运行
        // Eigen::MatrixX3d mat_x3d{{1, 2},{3, 4},{5, 6}};
        // LogInfo() << "mat_x3d: " << mat_x3d;
     }
}
}